//
//  recv_service_replies.hpp
// ~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2013-2014 Razvan Coca (razvan dot coca at  gmail dot com)
// This is mostly generated code. Generator is distributed under GPL. Edit it to suit your needs.
// 


#ifndef recv_service_replies_hpp
#define recv_service_replies_hpp
#include <boost/bind.hpp>
#include <boost/bind/protect.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/enable_shared_from_this.hpp>
#include <boost/asio.hpp>

#include "patterns/command.hpp"
#include "patterns/handlers.hpp"

#include "logging/logging.hpp"

namespace pcmd=patterns::command;
namespace phdl=patterns::handlers;
namespace ba=boost::asio;
namespace bs=boost::system;
namespace bt=boost::posix_time;

#include "components/defs/util_types.hpp"
#include "components/defs/client_processor.hpp"
#include "components/network/recv_service_reply.hpp"
#include "components/protocol/decode_enc_pb_reply.hpp"
#include "components/defs/handler_types.hpp"

namespace components{
namespace protocol{



class recv_service_replies :public boost::enable_shared_from_this<recv_service_replies>, private boost::noncopyable
{
private:
    std::string name_;

    ba::io_service& ios_;

    ba::ip::udp::socket& msocket_;

    crypto_buf_t& iv_;

    crypto_buf_t& key_;

    stats_message_client_processor& message_processor_;

    bytes_vector_t recv_buf_;

    std::string decrypt_buf_;

    udp_endpoint_t peer_;

    boost::shared_ptr<components::protocol::decode_enc_pb_reply> decode_enc_pb_reply_;

    boost::shared_ptr<components::network::recv_service_reply> recv_service_reply_;

    recv_service_replies (ba::io_service& ios, ba::ip::udp::socket& msocket, crypto_buf_t& iv, crypto_buf_t& key, stats_message_client_processor& message_processor) ;

    pcmd::action_t op_recv_service_reply_;

public:
    typedef boost::shared_ptr<recv_service_replies> pointer;

    bool cancel () ;

    static boost::shared_ptr<recv_service_replies> create (ba::io_service& ios, ba::ip::udp::socket& msocket, crypto_buf_t& iv, crypto_buf_t& key, stats_message_client_processor& message_processor) ;

    void handle_decode_enc_pb_reply (std::vector<stats_message_t>& replies,const crypto_error& eec) ;

    void handle_recv_service_reply (const bs::error_code& ec, std::size_t bytes_transferred) ;

    void init_components () ;

    virtual  ~recv_service_replies () ;
    template<typename Handler >
    void adapt_recv(Handler handler,const bs::error_code& ec, std::size_t bytes_transferred)
    {
        CryptoPP::Exception eec(CryptoPP::Exception::NOT_IMPLEMENTED,std::string("Success"));
        handler(ec,eec);
    }
    template<typename Handler >
    void adapt_decrypt(Handler handler,const crypto_error& eec)
    {
        bs::error_code ec;
        handler(ec,eec);
    }
    template<typename Handler >
    bool exec(std::vector<stats_message_t>& replies, Handler& handler) {
        try{
            LOG(INFO)<<name_<<"::"<<__FUNCTION__;
            init_components();
            phdl::transfer_handler_t
                    bound_handle_recv_service_reply = boost::bind(&recv_service_replies::handle_recv_service_reply,shared_from_this(),_1,_2);
            phdl::crypto_handler_t
                    bound_handle_decode_enc_pb_reply = boost::bind(&recv_service_replies::handle_decode_enc_pb_reply,shared_from_this(),boost::ref(replies),_1);

            phdl::transfer_handler_t
                    top_recv=boost::bind(&recv_service_replies::adapt_recv<Handler>,shared_from_this(),boost::protect(handler),_1,_2);
            phdl::crypto_handler_t
                    top_encr=boost::bind(&recv_service_replies::adapt_decrypt<Handler>,shared_from_this(),boost::protect(handler),_1);

            phdl::crypto_handler_t
                    composed_decr=phdl::branch_compose(bound_handle_decode_enc_pb_reply,top_encr,{});
            pcmd::action_t op_decode_enc_pb_reply = pcmd::wrap(decode_enc_pb_reply_,boost::ref(recv_buf_),boost::ref(decrypt_buf_),composed_decr);

            phdl::transfer_handler_t
                    composed_recv=phdl::branch_compose(bound_handle_recv_service_reply,top_recv,op_decode_enc_pb_reply,{0});
            op_recv_service_reply_ = pcmd::wrap(recv_service_reply_,boost::ref(peer_),boost::ref(recv_buf_),composed_recv);


            return pcmd::invoke(op_recv_service_reply_);
        }
        catch(std::exception &e){
            LOG(WARNING)<<name_<<"::"<<__FUNCTION__<<":"<<e.what();
            cancel();
            return false;
        }
        
    }
};

}//end namespace protocol
}//end namespace components

#endif /*#ifdef recv_service_replies_hpp*/
